package wvtools.extend;

import java.io.BufferedWriter;
import java.io.File;
import java.io.PrintWriter;
import java.io.Writer;

import edu.udo.cs.wvtool.generic.output.WVTOutputFilter;
import edu.udo.cs.wvtool.main.WVTWordVector;

/**
 * This class represents a mechanism, by which word vectors are stored to a
 * character stream. The format of the file is the following:
 * 
 * <name_of_source1>; <value11> <value12> ... <name_of_source2>; <value21>
 * <value22> ... ...
 * 
 * or, if you chose to store them in a sparse format:
 * 
 * <name_of_source1>; <index>:<value> <index>:<value> ... ...
 * 
 * @author Huangcd
 */
public class WordVectorWriterExtend implements WVTOutputFilter
{
    private final PrintWriter out;

    private final boolean     sparse;

    private final boolean     idAsAttribute;

    private final boolean     useLabel;

    private int               offset = 0;

    /**
     * Create a new instance of WordVectorFile
     * 
     * @param out
     *            the stream to which to write the vectors
     * @param sparse
     *            should the vectors be written in sparse format
     * 
     */
    public WordVectorWriterExtend(Writer out, boolean sparse)
    {
        this(out, sparse, false, false, 0);
    }

    /**
     * Create a new instance of WordVectorFile
     * 
     * @param out
     *            the stream to which to write the vectors
     * @param sparse
     *            should the vectors be written in sparse format
     * @param idAsAttribute
     *            write the id as attribute at the end of each line or in front
     *            of the word vector, separated by a semicolon
     * @param useLabel
     *            should the label information be used as additional attribute
     */
    public WordVectorWriterExtend(Writer out, boolean sparse,
            boolean idAsAttribute, boolean useLabel, int offset)
    {
        this.idAsAttribute = idAsAttribute;
        this.out = new PrintWriter(new BufferedWriter(out));
        this.sparse = sparse;
        this.useLabel = useLabel;
        this.offset = offset;
    }

    @Override
    public void write(WVTWordVector wv)
    {
        String id;
        int cutIndex = wv.getDocumentInfo().getSourceName().lastIndexOf(
                File.separator);

        if (cutIndex > 0)
            id = wv.getDocumentInfo().getSourceName().substring(cutIndex + 1);
        else
            id = wv.getDocumentInfo().getSourceName();

        int label = wv.getDocumentInfo().getClassValue();

        if (this.out != null)
        {
            double[] v = wv.getValues();

            if (!idAsAttribute)
                this.out.print(id + ";");
            else if (sparse)
                this.out.print("id:" + id);
            else
                this.out.print(id);

            for (int i = 0; i < v.length; i++)
            {
                if (sparse)
                {
                    if (v[i] > 0.0)
                    {
                        this.out.print(" " + (i + offset) + ":" + v[i]);
                    }
                }
                else
                    this.out.print(" " + v[i]);
                if (i % 100 == 0)
                    this.out.flush();
            }

            if (useLabel)
                this.out.print(" " + label);

            this.out.println();
            this.out.flush();
        }
    }

    public void close()
    {
        this.out.close();
    }
}
